﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using VideoAnalysisCloudPlatform.Website.Models;
using VideoEncoder;

namespace ExtractKeyFrame.Web.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 将切片文件上传
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload()
        {
            string fileName = Request["name"];
            string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//设置临时存放文件夹名称
            int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
            var guid = Request["guid"];//前端传来的GUID号
            var dir = Server.MapPath("~/Upload");//文件上传目录
            DirectoryExists(dir);
            DirectoryExists(dir + @"/Videos");
            dir = Path.Combine(dir, fileRelName);//临时保存分块的目录
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            string filePath = Path.Combine(dir, index.ToString());//分块文件名为索引名，更严谨一些可以加上是否存在的判断，防止多线程时并发冲突
            var data = Request.Files["file"];//表单中取得分块文件
            if (data != null)//为null可能是暂停的那一瞬间
            {
                data.SaveAs(filePath);//报错
            }

            return Json(new { code = 200, desc = "接收完毕" }, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 合并文件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> Merge()
        {
            var guid = Request["guid"];//GUID
            var uploadDir = Server.MapPath("~/Upload");//服务器的Upload 文件夹 物理地址
            var fileName = Request["fileName"];//文件全名（包括扩展名）
            string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//获取文件名
            var dir = Path.Combine(uploadDir, fileRelName);//临时文件夹          
            var files = Directory.GetFiles(dir);//获得下面的所有文件
            string newVideoName = DateTime.Now.ToString("yyyyMMddHHmmssffff");
            string fileExtr = fileName.Substring(fileName.LastIndexOf('.'), (fileName.Length - fileName.LastIndexOf('.')));
            //视频文件存储相对地址
            string newFilePath = new StringBuilder()
                .Append("~/Upload/Videos/")
                .Append(newVideoName)
                .Append(fileExtr)
                .ToString();
            //视频文件存储物理地址
            var finalPath = Server.MapPath(newFilePath);
            FileStream fs;
            using (fs = new FileStream(finalPath, FileMode.Create))
            {
                foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序，保证从0-N Write
                {
                    var bytes = System.IO.File.ReadAllBytes(part);
                    fs.Write(bytes, 0, bytes.Length);
                    bytes = null;
                    System.IO.File.Delete(part);//删除分块
                }
                fs.Flush();
            }
            Directory.Delete(dir);//删除文件夹

            //关键帧集合对象
            var imageUrls = await GetImageUrl(uploadDir, finalPath);
            //视频信息
            var videoFile = await GetVideoInfo(finalPath);
            return Json("文件合并完成",JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 提取该视频的关键帧
        /// </summary>
        /// <param name="videoFile">视频文件</param>
        /// <param name="finalPath"></param>
        /// <param name="jpgPath"></param>
        /// <param name="secondTime"></param>
        private void ExtractKeyFrame(VideoFile videoFile, string finalPath, string jpgPath, int secondTime)
        {
            int uploadNum = jpgPath.IndexOf("Upload");
            string imagePath = jpgPath.Substring(uploadNum, jpgPath.Length - uploadNum);
        }


        /// <summary>
        /// 获取视频信息
        /// </summary>
        /// <param name="oriVideoPath">视频物理路径</param>
        /// <returns></returns>
        private async Task<VideoFile> GetVideoInfo(string oriVideoPath)
        {
            var client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:9000/");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            string requestString = string.Format("api/CreateImage?oriVideoPath={0}", oriVideoPath);
            var videoFile = await client.GetAsync(requestString)
                .ContinueWith(x => x.Result.Content.ReadAsAsync<VideoFile>(
                    new List<MediaTypeFormatter>() { new JsonMediaTypeFormatter() })); ;
            return await videoFile;
        }

        /// <summary>
        /// 生成截图
        /// </summary>
        /// <param name="uploadDir">服务器的Upload 文件夹 物理地址</param>
        /// <param name="oriVideoPath">视频全路径</param>
        /// <returns>截图路径</returns>
        private async Task<ImageObj> GetImageUrl(string uploadDir, string oriVideoPath)
        {
            var client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:9000/");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            string requestString = string.Format("api/CreateImage?uploadDir={0}&oriVideoPath={1}", uploadDir, oriVideoPath);
            var imageUrl = await client.GetAsync(requestString)
                .ContinueWith(x => x.Result.Content.ReadAsAsync<ImageObj>(
                    new List<MediaTypeFormatter>() { new JsonMediaTypeFormatter() })); ;
            return await imageUrl;
        }

        /// <summary>
        /// 判断目录是否存在
        /// </summary>
        /// <param name="path">指定目录</param>
        private void DirectoryExists(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
    }
}